import { AssetManager } from "cc";
import { GameCore } from "../../../Base/Class";
import { setClassName } from "../../../Base/Global";
import { Singleton } from "../../../Base/Singleton";
import { IGameSystem } from "../../../Interfaces/IGameSystem";
import { AssetInfo } from "../base/AssetInfo";
import { ResourceLoadClassNameConst, ResourceLoadSpace } from "../_h/Index";
import { ResourceLoadManager } from "./ResourceLoadManager";

interface IAssetInfoLoadStateImp{
    instanceId : number,
    isDone : boolean,
}

class ICollectionInfoImp {
    instanceId : number;
    assetInfoLoadStateList : Array<IAssetInfoLoadStateImp> = new Array<IAssetInfoLoadStateImp>();

    getLoadStateIsAllDone() : boolean { 
        for(var i = 0; i < this.assetInfoLoadStateList.length; i++)
        {
            if(!this.assetInfoLoadStateList[i].isDone)
            {
                return false;
            }
        }
        return true;
    }

    setLoadState(instanceId : number, loadState : boolean)
    {
        var index = this.assetInfoLoadStateList.findIndex((aImp)=>{
            return aImp.instanceId == instanceId;
        });
        if(index >= 0)
        {
            this.assetInfoLoadStateList[index].isDone = loadState;
        }
    }
    addLoadStateItem(instanceId : number)
    {
        this.assetInfoLoadStateList.push({instanceId : instanceId, isDone : false});
    }
}

// 下载多个资源的时候可以使用的容器
export class AssetCollectionLoadSystem extends GameCore.ClassBase implements IGameSystem.IUpdateSystem, ResourceLoadSpace.IAssetCollectionLoadSystem
{
    private assetCollectionList : Array<ResourceLoadSpace.IAssetCollectionInfo> = new Array<ResourceLoadSpace.IAssetCollectionInfo>();
    private waitLoadAssetList : Array<ICollectionInfoImp> = new Array<ICollectionInfoImp>();
    private updateCollectionIdList : Array<number> = new Array<number>();
    public AddAssetCollection(assetCollection : ResourceLoadSpace.IAssetCollectionInfo)
    {
        this.assetCollectionList.push(assetCollection);
        var instanceId = assetCollection.instanceId;

        var infoImp : ICollectionInfoImp = new ICollectionInfoImp();
        infoImp.instanceId = instanceId;

        assetCollection.assetInfos.forEach((assetInfo : AssetInfo)=>{
            var assetInfoInstanceId = assetInfo.instanceId;
            infoImp.addLoadStateItem(assetInfoInstanceId)
            Singleton.Instance(ResourceLoadManager).LoadAsset(assetInfo, (bundle : AssetManager.Bundle)=> {
                Singleton.Instance(AssetCollectionLoadSystem).LoadAssetCallBack(instanceId, assetInfoInstanceId, bundle);
            });
        })

        this.waitLoadAssetList.push(infoImp);
    }

    private LoadAssetCallBack(instanceId : number, assetInfoInstanceId : number, bundle : AssetManager.Bundle)
    {
        var _index = this.assetCollectionList.findIndex((oInfo)=>{
            return oInfo.instanceId == instanceId;
        });
        if(_index >= 0)
        {
            var collectionInfo = this.assetCollectionList[_index];
            var aIndex = collectionInfo.assetInfos.findIndex((aInfo)=>{return aInfo.instanceId == assetInfoInstanceId;})
            if(aIndex >= 0)
            {
                collectionInfo.SetAsset(collectionInfo.assetInfos[aIndex], bundle)
            }

            var index = this.waitLoadAssetList.findIndex((imp)=>{return imp.instanceId == instanceId});
            if(index >= 0)
            {
                var imp = this.waitLoadAssetList[index];
                imp.setLoadState(assetInfoInstanceId, true);
            }

            index =  this.updateCollectionIdList.indexOf(instanceId);
            if(index == -1)
            {
                this.updateCollectionIdList.push(instanceId);
            }
        }
        else
        {
            Singleton.Instance(ResourceLoadManager).UnloadAsset(bundle);
        }
    }
    
    Update(): void 
    {
        while(this.updateCollectionIdList.length > 0)
        {
            var instanceId = this.updateCollectionIdList.shift();
            var index = this.waitLoadAssetList.findIndex((imp)=>{return imp.instanceId == instanceId});
            if(index >= 0)
            {
                var imp = this.waitLoadAssetList[index];
                var isAllDone = imp.getLoadStateIsAllDone();
                if(isAllDone)
                {
                    var instanceId = imp.instanceId;
                    var _index = this.assetCollectionList.findIndex((collection)=>{
                        return collection.instanceId == instanceId;
                    });
                    if(_index >= 0)
                    {
                        this.assetCollectionList[_index].SetLoadDoneState();
                        this.assetCollectionList.slice(_index, 1);
                    }

                    this.waitLoadAssetList.slice(index ,1)
                }
            }
        }
    }
    
    public OnReleaseCollectionInfo(collectionInfo : ResourceLoadSpace.IAssetCollectionInfo)
    {
        collectionInfo.assetInfos.forEach((assetInfo : AssetInfo)=>{
            var bundle = collectionInfo.GetAsset(assetInfo)
            Singleton.Instance(ResourceLoadManager).UnloadAsset(bundle);
        });
    }
}
setClassName(AssetCollectionLoadSystem, ResourceLoadClassNameConst.AssetCollectionLoadSystemClassName)

